package com.icinfo.cloud.provider.punish.common.seal.utils;

import cn.hutool.cache.CacheUtil;
import cn.hutool.cache.impl.TimedCache;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpStatus;
import cn.hutool.http.HttpUtil;
import cn.hutool.http.Method;
import com.alibaba.fastjson.JSONObject;
import com.icinfo.cloud.provider.common.constant.Constant;
import com.icinfo.cloud.provider.common.dto.OcrData;
import com.icinfo.cloud.provider.common.exception.BusinessException;
import com.icinfo.cloud.provider.common.utils.FileUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.util.IOUtils;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.*;

/**
 * 中心的签章接口
 *
 * @author yunchao.peng
 * @create 2023-07-28 17:06
 */
@Slf4j
@Configuration
@ConfigurationProperties(prefix = "center-sign")
public class ChongQingCenterSignUtil {
    private static final TimedCache<String, String> timedCache = CacheUtil.newTimedCache(4);

    private static final String URL = "http://23.213.30.12:11001";

    /**
     * 获取签章的文件
     *
     * @return
     */
    public static byte[] getSignFileByte(File file, String sealCode) {
        String fileId = upload(file);
        List<PositionCenter> positions = filePosition(fileId, "签章处", Collections.singletonList("SEAL"));
        SealBindSignCenter sealBindSign = new SealBindSignCenter();
        sealBindSign.setThirdBizId("test not null");
        ArrayList<SealBindSignCenter.FileInfoBean> sealInfoBeans = new ArrayList<>();
        SealBindSignCenter.FileInfoBean fileInfoBean = new SealBindSignCenter.FileInfoBean();
        fileInfoBean.setFileId(fileId);
        SealBindSignCenter.FileInfoBean.SignInfoBean sealInfoBean = new SealBindSignCenter.FileInfoBean.SignInfoBean();
        PositionCenter position = positions.get(0);
        sealInfoBean.setPage(position.getPage());
        SealBindSignCenter.FileInfoBean.SignInfoBean.RectangleBean rectangleBean = new SealBindSignCenter.FileInfoBean.SignInfoBean.RectangleBean();
        BeanUtil.copyProperties(position, rectangleBean);
        sealInfoBean.setRectangle(rectangleBean);
        sealInfoBean.setSn(Constant.INTEGER_12);

        SealBindSignCenter.FileInfoBean.SignInfoBean.SealInfoBean sealInfo = new SealBindSignCenter.FileInfoBean.SignInfoBean.SealInfoBean();
        sealInfo.setBindCode(sealCode);
        sealInfoBean.setSealInfo(sealInfo);
        List<SealBindSignCenter.FileInfoBean.SignInfoBean> singInfo = new ArrayList<>();
        singInfo.add(sealInfoBean);
        fileInfoBean.setSignInfo(singInfo);
        sealInfoBeans.add(fileInfoBean);
        sealBindSign.setFileInfo(sealInfoBeans);
        SealFileCenter sealFile = sealBindSign(sealBindSign);
        return downLoad(sealFile.getFileList().get(0));
    }


    /**
     * token的获取
     *
     * @return
     */
    public static AuthToken getAuthToken() {
//        String token = timedCache.get("token");
//        if (StringUtils.isNotBlank(token)) {
//            log.info("中心签章接口缓存token========:" + token);
//            return JSONObject.parseObject(token, AuthToken.class);
//        }
        String url = URL + "/paas-api/gateway/paas-auth/oauth/token";
        log.info(url);
        HttpRequest post = HttpUtil.createPost(url);
        String tokenAuth = "Basic SnBuR3g2RzE2ODY2MjI2NTg4OTk6ek9oNWVmdzE2ODY2MjI2NTg4OTk=";
        setHeader(post, tokenAuth);

        HashMap<String, Object> param = new HashMap<>();
        param.put("grant_type", "aos_exchange_token");
        param.put("clientToken", "test123");
        param.put("userInfoUrl", "http://23.213.30.12:11000/digitalcqtemp/userinfo.json");
        post.form(param);
        String body = post.execute().body();
        log.info("获取授权接口详情,{}", body);
        JSONObject response = JSONObject.parseObject(body);
        if (HttpStatus.HTTP_OK == response.getInteger("code")) {
            AuthToken authToken = response.getObject("data", AuthToken.class);
//            timedCache.put("token", JSONObject.toJSONString(authToken), authToken.getExpiresIn().longValue() * 1000);
//            log.info("中心签章接口获取token========:" + JSONObject.toJSONString(authToken));
            return authToken;
        }
        throw new BusinessException("获取授权接口异常异常");
    }

    /**
     * 上传文件
     *
     * @return
     */
    public static String upload(File file) {
        HttpRequest post = createAuthPost("/paas-api/gateway/paas-standard-sdk/file/upload");
        HashMap<String, Object> param = new HashMap<>();
        param.put("file", file);
        post.form(param);
        String body = post.execute().body();
        log.info("获取文件上传接口详情,{}", body);
        JSONObject response = JSONObject.parseObject(body);
        if (HttpStatus.HTTP_OK == response.getInteger("code")) {
            return response.getJSONObject("data").getString("fileId");
        }
        throw new BusinessException("上传接口失败");
    }


    /**
     * 文件签章地址获取
     *
     * @param fileId
     * @param keyWord
     * @param positionType
     * @return
     */
    public static List<PositionCenter> filePosition(String fileId, String keyWord, List<String> positionType) {
        HttpRequest authPost = createAuthPost("/paas-api/gateway/paas-toolbox/file/filePosition");
        JSONObject requestBody = new JSONObject();
        requestBody.put("fileId", fileId);
        requestBody.put("keyWord", keyWord);
        requestBody.put("positionType", positionType);
        log.info("获取文件关键字位置接口请求参数:{}", requestBody.toJSONString());
        authPost.body(requestBody.toJSONString());
        String body = authPost.execute().body();
        log.info("获取文件关键字位置接口详情,{}", body);
        JSONObject response = JSONObject.parseObject(body);
        if (HttpStatus.HTTP_OK == response.getInteger("code")) {
            return response.getJSONObject("data").getJSONArray("positionList").toJavaList(PositionCenter.class);
        }
        throw new BusinessException("获取印章位置接口失败");
    }

    /**
     * 批量签章接口
     *
     * @param sealBindSign
     * @return
     */
    public static SealFileCenter sealBindSign(SealBindSignCenter sealBindSign) {
        HttpRequest authPost = createAuthPost("/paas-api/gateway/paas-standard-sdk/sign/sealBindSign");
        String requestBody = JSONObject.toJSONString(sealBindSign);
        log.info("批量签章请求参数,{}", requestBody);
        authPost.body(requestBody);
        String body = authPost.execute().body();
        log.info("获取批量签章结果接口详情,{}", body);
        JSONObject response = JSONObject.parseObject(body);
        if (HttpStatus.HTTP_OK == response.getInteger("code")) {
            return response.getObject("data", SealFileCenter.class);
        }
        throw new BusinessException("签署印章异常");
    }

    public static void main(String[] args) {
        // -Djava.net.preferIPv4Stack=true  VPN要加这个在 vm param
//        File file = new File("C:\\Users\\hzhb\\Desktop\\印章测试.pdf");
//        byte[] signFileByte = getSignFileByte(file, "91c93f52ae8067f93f6a609494563e61823edff8071e1f9ff6696f6dd07917d45f4ec5d5de3cd931b8a5fa620803d858");
//        System.out.println(signFileByte.length);
//        byte[] bytes = downLoad("223248759323142144");
//        String data = Base64.encodeBase64String(bytes);
//        System.out.println(data);

        File file = new File("C:\\Users\\hzhb\\Desktop\\ecbd69d9041ca40db16bde75ea649d7.jpg");
        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream(file);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        MultipartFile multipartFile = null;
        try {
            multipartFile = new MockMultipartFile("file", file.getName(), "text/plain", IOUtils.toByteArray(fileInputStream));
        } catch (IOException e) {
            e.printStackTrace();
        }
        List<OcrData> ocrData =  doOcr(multipartFile);
        System.out.println(JSONObject.toJSONString(ocrData));
    }


    /**
     * ocr 结果值
     *
     * @param file
     * @return
     */
    public static List<OcrData> doOcr(MultipartFile file) {
        // todo 测试数据
//        JSONObject jsonObject = JSONObject.parseObject("{\n" +
//                "\t\"code\": \"0\",\n" +
//                "\t\"msg\": \"操作成功！\",\n" +
//                "\t\"data\": [\n" +
//                "\t\t{\n" +
//                "\t\t\t\"entities\": [\n" +
//                "\t\t\t\t{\n" +
//                "\t\t\t\t\t\"end_offset\": 10,\n" +
//                "\t\t\t\t\t\"id\": 72,\n" +
//                "\t\t\t\t\t\"label\": \"性别\",\n" +
//                "\t\t\t\t\t\"start_offset\": 9,\n" +
//                "\t\t\t\t\t\"entity\": \"男\"\n" +
//                "\t\t\t\t},\n" +
//                "\t\t\t\t{\n" +
//                "\t\t\t\t\t\"end_offset\": 26,\n" +
//                "\t\t\t\t\t\"id\": 73,\n" +
//                "\t\t\t\t\t\"label\": \"出生日期\",\n" +
//                "\t\t\t\t\t\"start_offset\": 17,\n" +
//                "\t\t\t\t\t\"entity\": \"1993年1月6日\"\n" +
//                "\t\t\t\t},\n" +
//                "\t\t\t\t{\n" +
//                "\t\t\t\t\t\"end_offset\": 79,\n" +
//                "\t\t\t\t\t\"id\": 74,\n" +
//                "\t\t\t\t\t\"label\": \"身份证号\",\n" +
//                "\t\t\t\t\t\"start_offset\": 61,\n" +
//                "\t\t\t\t\t\"entity\": \"130182199301060913\"\n" +
//                "\t\t\t\t},\n" +
//                "\t\t\t\t{\n" +
//                "\t\t\t\t\t\"end_offset\": 6,\n" +
//                "\t\t\t\t\t\"id\": 75,\n" +
//                "\t\t\t\t\t\"label\": \"姓名\",\n" +
//                "\t\t\t\t\t\"start_offset\": 3,\n" +
//                "\t\t\t\t\t\"entity\": \"彭云超\"\n" +
//                "\t\t\t\t},\n" +
//                "\t\t\t\t{\n" +
//                "\t\t\t\t\t\"end_offset\": 14,\n" +
//                "\t\t\t\t\t\"id\": 76,\n" +
//                "\t\t\t\t\t\"label\": \"民族\",\n" +
//                "\t\t\t\t\t\"start_offset\": 13,\n" +
//                "\t\t\t\t\t\"entity\": \"汉\"\n" +
//                "\t\t\t\t},\n" +
//                "\t\t\t\t{\n" +
//                "\t\t\t\t\t\"end_offset\": 53,\n" +
//                "\t\t\t\t\t\"id\": 77,\n" +
//                "\t\t\t\t\t\"label\": \"住址\",\n" +
//                "\t\t\t\t\t\"start_offset\": 29,\n" +
//                "\t\t\t\t\t\"entity\": \"河北省石家庄市藁城区兴 安镇冯马村北环东路39号\"\n" +
//                "\t\t\t\t}\n" +
//                "\t\t\t],\n" +
//                "\t\t\t\"classes\": [\n" +
//                "\t\t\t\t\"身份证\"\n" +
//                "\t\t\t],\n" +
//                "\t\t\t\"relations\": []\n" +
//                "\t\t}\n" +
//                "\t]\n" +
//                "}");
//        return jsonObject.getJSONArray("data").getJSONObject(0).getJSONArray("entities").toJavaList(OcrData.class);

        HttpRequest authPost = createAuthPostOcr("/image-classification/tpfl");
        File oriFile = null;
        try {
            oriFile = FileUtil.multipartFileToFile(file);
        } catch (Exception e) {
            e.printStackTrace();
        }
        HashMap<String, Object> param = new HashMap<>();
        param.put("file", oriFile);
        param.put("category", "doc");
        authPost.form(param);
        String body = authPost.execute().body();
        log.info("获取重庆ocr的结果:{}", body);
        JSONObject response = JSONObject.parseObject(body);
        if (Constant.STRING_0.equals(response.getString("code"))) {
            return response.getJSONArray("data").getJSONObject(0).getJSONArray("entities").toJavaList(OcrData.class);
        }
        throw new BusinessException("获取重庆ocr结果错误:" + body);
    }

    private static HttpRequest createAuthPostOcr(String url) {
        url = URL + url;
        HttpRequest post = HttpUtil.createPost(url);
        HashMap<String, String> defHeader = getDefHeader("28");
        post.addHeaders(defHeader);
        return post;
    }


    /**
     * 下载签章接口
     *
     * @param fileId
     * @return
     */
    public static byte[] downLoad(String fileId) {
        log.info("下载文件接口,文件id {}", fileId);
        HttpRequest authGet = createAuthGet("/paas-api/gateway/paas-standard-sdk/file/download/" + fileId);
        return authGet.execute().bodyBytes();
    }

    /**
     * get请求
     *
     * @param url
     * @return
     */
    private static HttpRequest createAuthGet(String url) {
        HttpRequest authPost = createAuthPost(url);
        authPost.setMethod(Method.GET);
        return authPost;
    }


    /**
     * 非token的默认请求
     *
     * @param url
     * @return
     */
    private static HttpRequest createAuthPost(String url) {
        AuthToken authToken = getAuthToken();
        url = URL + url;
        HttpRequest post = HttpUtil.createPost(url);
        setHeader(post, "Bearer " + authToken.getAccessToken());
        return post;
    }

    /**
     * 请求头
     *
     * @param post
     */
    private static void setHeader(HttpRequest post, String authorization) {
        HashMap<String, String> header = getDefHeader();
        header.put("Authorization", authorization);
        post.addHeaders(header);
    }

    /**
     * 默认值
     *
     * @return
     */
    private static HashMap<String, String> getDefHeader() {
        HashMap<String, String> header = new HashMap<>(2);
        header.put("Application-Ability", "18");
        header.put("Applicant-Company", "1510104311760801794");
        return header;
    }

    private static HashMap<String, String> getDefHeader(String ability) {
        HashMap<String, String> header = new HashMap<>(2);
        header.put("Application-Ability", ability);
        header.put("Applicant-Company", "1510104311760801794");
        return header;
    }

}
